package logic

import (
	"sync"
	"yundian/internel/app/dao"
	"yundian/internel/app/models/statistics"
)

type TaskStatisticsPlaceLogic struct {
}

func NewTaskStatisticsPlaceLogic() *TaskStatisticsPlaceLogic {
	return &TaskStatisticsPlaceLogic{}
}

// 动销门店数据分析
func (t *TaskStatisticsPlaceLogic) StatisticsByTypeByHaveOrders(dateList []string) ( r bool) {
	for _, d := range dateList {
		if ok := dao.NewStatisticsDao().InsertOrderToTemp(d).Unwrap().(bool); ok { // 订单临时表
			if ok := dao.NewStatisticsDao().InsertDividendsToTemp(d).Unwrap().(bool); ok { // 分红临时表
				if ok := dao.NewStatisticsDao().InsertOrdersUserRelevancyToTemp(d).Unwrap().(bool); ok {
					placeIds := dao.NewStatisticsDao().GetPlaceIdsByOrders(d).Unwrap().([]int) // 动销门店
					userIds := dao.NewStatisticsDao().GetPlaceUserIdsByOrders(d).Unwrap().([]int) // 动销商户

					maxGoroutine := 2 // 开启协程的大小
					var pool chan struct{}
					pool = make(chan struct{}, maxGoroutine) // 协程池
					var wg sync.WaitGroup
					for _,id := range placeIds {
						wg.Add(1)
						pool <- struct{}{}
						go func(str string, placeId int) {
							defer wg.Done()
							defer func() {
								<- pool
							}()
							t.OrderAndIncomeStatisticsByPlace(str, placeId)
						}(d, id)
					}

					var poolUser chan struct{}
					poolUser = make(chan struct{}, maxGoroutine) // 协程池
					for _,id := range userIds {
						wg.Add(1)
						poolUser <- struct{}{}
						go func(str string, userId int) {
							defer wg.Done()
							defer func() {
								<- poolUser
							}()
							t.OrderAndIncomeStatisticsByPlaceUser(str, userId)
						}(d, id)
					}
					wg.Wait()
					dao.NewStatisticsDao().DeleteTempTable(d) // 删除临时表
				}
			}
		}
	}
	return true
}

// 动销门店
func (t *TaskStatisticsPlaceLogic) OrderAndIncomeStatisticsByPlace(dateStr string, placeId int)  {

}

// 动销商户
func (t *TaskStatisticsPlaceLogic) OrderAndIncomeStatisticsByPlaceUser(dateStr string, userId int) ( ok bool) {
	m := &statistics.StatisticsPlaceUserModel{}
	var mEnd, mComplete, mCancel, mSy dao.CountSettlement
	var mAllDraw, mDraw, mNoDraw, mSmallDraw, mcNodraw, cNodraw dao.CountSettlement
	var totalDevices, totalIncome int64
	var directUsers, directPlaces, totalUsers, totalPlaces, userIds []int
	var wx, qrcode, qrcodeWait, qrcodeSuccess, qrcodeFail dao.CountSettlement

	userIds = append(userIds, userId)

	var w sync.WaitGroup
	w.Add(4)
	go func() {
		defer w.Done()
		directUsers = dao.NewStatisticsDao().CountUsersByParentId(userIds, dateStr).Unwrap().([]int) // 直属团队数
		directPlaces = dao.NewStatisticsDao().CountPlacesByUserId(userId, dateStr).Unwrap().([]int) // 直属门店数
		totalUsers = t.GetTotalTeams(userId, dateStr) // 团队总数
		totalPlaces = dao.NewStatisticsDao().CountPlacesByUserIds(totalUsers, dateStr).Unwrap().([]int) // 门店总数
		totalDevices = dao.NewStatisticsDao().CountDevicesByPlaceIds(totalPlaces).Unwrap().(int64) // 设备总数
	}()
	go func() {
		defer w.Done()
		mEnd = dao.NewStatisticsDao().QueryUserTotalOrderByState(0, userId, dateStr).Unwrap().(dao.CountSettlement)
		mComplete = dao.NewStatisticsDao().QueryUserTotalOrderByState(5, userId, dateStr).Unwrap().(dao.CountSettlement)
		mCancel = dao.NewStatisticsDao().QueryUserTotalOrderByState(3, userId, dateStr).Unwrap().(dao.CountSettlement)
		mSy = dao.NewStatisticsDao().QueryUserTotalOrderByState(7, userId, dateStr).Unwrap().(dao.CountSettlement)

		totalIncome = dao.NewStatisticsDao().QueryUserTotalIncomeByUserId(userId, dateStr).Unwrap().(int64)
	}()
	go func() {
		defer w.Done()
		mAllDraw = dao.NewStatisticsDao().QueryUserTotalOrderByDraw(4, 0, userId, dateStr).Unwrap().(dao.CountSettlement)
		mDraw = dao.NewStatisticsDao().QueryUserTotalOrderByDraw(1, 0, userId, dateStr).Unwrap().(dao.CountSettlement)
		mNoDraw = dao.NewStatisticsDao().QueryUserTotalOrderByDraw(2, 0, userId, dateStr).Unwrap().(dao.CountSettlement)
		mSmallDraw = dao.NewStatisticsDao().QueryUserTotalOrderByDraw(3, 0, userId, dateStr).Unwrap().(dao.CountSettlement)
		mcNodraw = dao.NewStatisticsDao().QueryUserTotalOrderByDraw(2, 5, userId, dateStr).Unwrap().(dao.CountSettlement)
		cNodraw = dao.NewStatisticsDao().QueryUserTotalOrderByDraw(2, 3, userId, dateStr).Unwrap().(dao.CountSettlement)
	}()
	go func() {
		defer w.Done()
		wx = t.QueryTotalCashLog(dateStr, 0, 0, userId)
		qrcode = t.QueryTotalCashLog(dateStr, 2, 0, userId)
		qrcodeWait = t.QueryTotalCashLog(dateStr, 2, 1, userId)
		qrcodeSuccess = t.QueryTotalCashLog(dateStr, 2, 2, userId)
		qrcodeFail = t.QueryTotalCashLog(dateStr, 2, 3, userId)
	}()
	w.Wait()

	m.DateStr = dateStr // 日期
	m.UserId = int64(userId) // 用户ID

	m.TotalTeam = len(totalUsers) // 团队总数
	m.TotalPlace = len(totalPlaces) // 门店总数
	m.TotalDirectPlace = len(directPlaces)  // 直属下级
	m.TotalDirectTeam = len(directUsers)  // 直属门店
	m.TotalDevices = totalDevices // 设备总数

	m.TotalOrders = mEnd.Total          // 当天订单数
	m.TotalComplete = mComplete.Total   // 当天完成的订单数
	m.TotalCancel = mCancel.Total       // 当天撤销的订单数
	m.TotalSy = mSy.Total               // 当天守约的订单数
	m.TotalCompleteNodraw = mcNodraw.Total
	m.TotalCancelNodraw = cNodraw.Total

	m.TotalAllDraw = mAllDraw.Total     // 总抽单数
	m.TotalDraw = mDraw.Total           // 普通 抽单数
	m.TotalSmalldraw = mSmallDraw.Total
	m.TotalNodraw = mNoDraw.Total       // 未抽单数

	m.TotalIncome = totalIncome                 // 用户收益

	m.SettlementTotal = mEnd.Money
	m.SettlementComplete = mComplete.Money
	m.SettlementCancel = mCancel.Money
	m.SettlementNormalTotal = mcNodraw.Money
	m.SettlementCancelNodraw = cNodraw.Money

	m.SettlementAlldraw = mAllDraw.Money
	m.SettlementDraw = mDraw.Money
	m.SettlementNodraw = mNoDraw.Money
	m.SettlementSmalldraw = mSmallDraw.Money

	m.WeixinTotal = wx.Total
	m.WeixinMoney = wx.Money
	m.QrcodeTotal = qrcode.Total
	m.QrcodeSuccessTotal = qrcodeSuccess.Total
	m.QrcodeSuccessMoney = qrcodeSuccess.Money
	m.QrcodeWaitTotal = qrcodeWait.Total
	m.QrcodeWaitMoney = qrcodeWait.Money
	m.CashFailedTotal = qrcodeFail.Total
	m.CashFailedMoney = qrcodeFail.Money

	ok = dao.NewStatisticsDao().InsertStatisticsPlaceUser(m).Unwrap().(bool)
	return
}

// 获取总团队人数
func (t *TaskStatisticsPlaceLogic) GetTotalTeams(id int, dateStr string) []int {
	isLoop := true
	var userIds, ids []int
	ids = append(ids, id)
	for isLoop {
		tempUserIds := dao.NewStatisticsDao().CountUsersByParentId(ids, dateStr).Unwrap().([]int)
		if len(tempUserIds) == 0 {
			isLoop = false
		} else {
			userIds = append(userIds, tempUserIds...)
			ids = tempUserIds
		}
	}
	return userIds
}


// QueryTotalCashLog
func (t *TaskStatisticsPlaceLogic) QueryTotalCashLog(dateStr string, transferType, state, id int) dao.CountSettlement {
	cashLog := dao.NewStatisticsDao().QueryUserTotalCashLog(dateStr, transferType, state, id).Unwrap().(dao.CountSettlement) // 创建时间订单总数
	return cashLog
}


//
//// 未动销门店数据分析
//func (t *TaskStatisticsPlaceLogic) StatisticsByTypeByNoHaveOrders(dateStr string) ( r bool) {
//	if ok := dao.NewStatisticsDao().InsertOrderToTemp(dateStr).Unwrap().(bool); ok { // 订单临时表
//		if ok := dao.NewStatisticsDao().InsertDividendsToTemp(dateStr).Unwrap().(bool); ok { // 分红临时表
//			if ok := dao.NewStatisticsDao().InsertOrdersUserRelevancyToTemp(dateStr).Unwrap().(bool); ok { // 用户关联表-临时
//				ids := dao.NewStatisticsDao().GetUserIdsByOrders(dateStr).Unwrap().([]int) // 动销用户列表
//				userIds := dao.NewStatisticsDao().GetOtherUserIdsByIds(ids, dateStr).Unwrap().([]int) // 未动销用户数
//				maxGoroutine := 4 // 开启协程的大小
//				var pool chan struct{}
//				pool = make(chan struct{}, maxGoroutine) // 协程池
//				var wg sync.WaitGroup
//				for _,id := range userIds {
//					wg.Add(1)
//					pool <- struct{}{}
//					go func(str string, userId int) {
//						defer wg.Done()
//						defer func() {
//							<- pool
//						}()
//						t.OrderAndIncomeStatisticsOther(str, userId)
//					}(dateStr, id)
//				}
//				wg.Wait()
//				dao.NewStatisticsDao().DeleteTempTable(dateStr)
//			}
//		}
//	}
//	return true
//}
//
//// 单个门店数据分析
//func (t *TaskStatisticsPlaceLogic) StatisticsByTypeByUserId(dateStr string, userId int) ( r bool) {
//	if ok := dao.NewStatisticsDao().InsertOrderToTemp(dateStr).Unwrap().(bool); ok {
//		if ok := dao.NewStatisticsDao().InsertDividendsToTemp(dateStr).Unwrap().(bool); ok {
//			if ok := dao.NewStatisticsDao().InsertOrdersUserRelevancyToTemp(dateStr).Unwrap().(bool); ok {
//				if ok := t.OrderAndIncomeStatistics(dateStr, userId); ok {
//					dao.NewStatisticsDao().DeleteTempTable(dateStr) // 删除临时表
//					return true
//				}
//			}
//		}
//	}
//	return false
//}
//




